const HttpException = require("../exceptions/http_expetion");
const { validateCreateArticle } = require("../utils/validate/article_validate");
const Article = require("../models/article");
const User = require("../models/user");
const { getSlug } = require("../utils/slug");
const Tag = require("../models/tag");
const sequelize = require("../db/sequelize");

//单个文章优化（标签优化、作者优化）
const handleArticle = (article, author)=>{
  //标签优化
  const newTags = []
  for (const i of article.dataValues.tags) {
    newTags.push(i.name)
  }
  article.dataValues.tags = newTags

  //作者优化
  delete author.dataValues.password
  delete author.dataValues.email
  article.dataValues.author = author

  return article.dataValues
}

//多个文章优化（标签优化、作者优化）
const handleArticles = async(currentEmail,article)=>{
  // 标签优化
  const newTags = []
  for (let i of article.dataValues.tags) {
    newTags.push(i.name)
  }
  article.dataValues.tags = newTags
  
  //作者优化
  let { username, email , bio, avatar} = article.dataValues.user 
  let author = { username,email,bio,avatar }
  delete article.dataValues.user
  article.dataValues.author = author
  
  //喜欢文章
  const favoriteCount = await article.countUsers()
  if(favoriteCount==0){
    article.dataValues.isFavorite = false
    article.dataValues.favoriteCount = 0
    return article.dataValues
  }
  if(currentEmail){
    article.dataValues.isFavorite = false
    article.dataValues.favoriteCount = favoriteCount
    return article.dataValues
  }
    const allFavoriteUsers = await article.getUsers()
    let allFavoriteUsersEmails = []
    allFavoriteUsers.forEach(user=>{
      allFavoriteUsersEmails.push(user.email)
    })
    let isFavorite =  allFavoriteUsersEmails.includes(currentEmail)
  
    article.dataValues.isFavorite = isFavorite
    article.dataValues.favoriteCount = favoriteCount
  
    return article.dataValues
  

}

//创建文章
module.exports.createArticle = async (req, res, next) => {
  try {
    //获取请求数据
    const { title, description, body, tags } = req.body.article
    //获取内容验证
    let { error, validate } = validateCreateArticle(title, description, body)
    if (!validate) {
      throw new HttpException(401, '文章内容不存在！！！', error)
    }
    //获取作者信息
    const { email } = req.user
    const author = await User.findByPk(email)
    if (!author) {
      throw new HttpException(401, '作者账号不存在！！！', 'author is not found!!!')
    }
    //创建文章
    //  生成文章别名
    let slug = getSlug()
    //  存储数据：
    let article = await Article.create({
      slug,
      title,
      description,
      body,
      userEmail: author.email
    })
    //存储文章和标签的处理
    //  自定义
    //  数据库已有
    if (tags) {
      for (const i of tags) {
        let existTag = await Tag.findByPk(i)
        let newTag
        if (!existTag) {
          newTag = await Tag.create({ name: i })
          await article.addTag(newTag)
        } else {
          await article.addTag(existTag)
        }
      }
    }

    //返回数据 (文章、标签、作者)
    article = await Article.findByPk(slug, { include: Tag }) //追加标签

    //标签优化

    //作者优化

    article = handleArticle(article, author) //文章优化抽离

    res.status(201)
      .json({
        status: 1,
        message: '创建文章成功！！！',
        data: article
      })
  } catch (err) {
    next(err);
  }
};


//获取文章：获取单个
module.exports.getArticle = async (req, res, next) => {
  try {
    //获取参数：文章别名slug(文章唯一标识符)
    const { slug } = req.params
    //获取信息：根据slug获取文章相关信息
    let article = await Article.findByPk(slug, { include: Tag })
    //获取作者信息
    const author = await article.getUser()
    //返回数据处理
    article = handleArticle(article, author)
    //返回响应数据
    res.status(200)
      .json({
        status: 1,
        message: '获取单个文章成功！！！',
        data: article
      })

  } catch (err) {
    next(err);
  }
};


//获取文章：获取已关注作者的文章
module.exports.getFollowArticle = async (req, res, next) => {
  try {
    //获取登录用户
    const fansEmail = req.user.email
    //获取当前登录用户关注的作者
    const query = `SELECT userEmail FROM followers WHERE followerEmail="${fansEmail}"`
    const followAuthors = await sequelize.query(query)
    //判断获取文章是否为空
    if (followAuthors[0].length == 0) {
      return res.status(200)
        .json({
          status: 1,
          message: '当前用户没有关注的作者--获取文章为空！！！',
          data: []
        })
    }
    //获取作者email
    let followAuthorEmails = []
    for (const i of followAuthors[0]) {
      followAuthorEmails.push(i.userEmail)
    }
    //获取作者文章
    let {count,rows} = await Article.findAndCountAll({
      distinct:true, //去重
      where: {
        UserEmail: followAuthorEmails
      },
      include: [Tag, User]
    })
    //作者信息-文章-标签处理
    let articles = []
    for (const i of rows) {
      let handleArticle = await handleArticles(fansEmail,i)
      articles.push(handleArticle)
    }
    //响应数据
    res.status(200)
      .json({
        status: 1,
        message: '已关注作者的文章获取成功！！！',
        data: {articles,articlesCount:count}
      })

  } catch (err) {
    next(err);
  }
};


//获取文章：获取全局文章
module.exports.getArticles = async (req, res, next) => {
  try {
    //获取登录用户
    const email = req.user ? req.user.email : null
    //获取条件参数
    const {tag,author,limit=10,offset=0} = req.query
    //获取文章数组
    let result = []

    if(tag&&!author){  //按标签查询
      
      result = await Article.findAndCountAll({
        distinct:true, //去重
        include:[{
          model:Tag,
          attributes:['name'],
          where:{name:tag}
        },{
          model:User,
          attributes:['email','username','bio','avatar']
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }else if(!tag&&author){  //按作者查询
      result = await Article.findAndCountAll({
        distinct:true, //去重
        include:[{
          model:Tag,
          attributes:['name']
        },{
          model:User,
          attributes:['email','username','bio','avatar'],
          where:{name:author}
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }else if(tag&&author){  //按标签和作者查询
      result = await Article.findAndCountAll({
        distinct:true, //去重
        include:[{
          model:Tag,
          attributes:['name'],
          where:{name:tag}
        },{
          model:User,
          attributes:['email','username','bio','avatar'],
          where:{name:author}
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }else{ //剩余情况
      result = await Article.findAndCountAll({
        distinct:true, //去重
        include:[{
          model:Tag,
          attributes:['name'],
        },{
          model:User,
          attributes:['email','username','bio','avatar']
        }],
        limit:parseInt(limit),
        offset:parseInt(offset)
      })
    }
    
    let {count,rows} = result
    //文章数据处理
    let articles = []
    for (const i of rows) {
      let handleArticle = await handleArticles(email,i)
      articles.push(handleArticle)
    }
    //响应数据
    res.status(200)
      .json({
        status: 1,
        message: '文章获取成功！！！',
        data: {articles,articlesCount:count}
      })

  } catch (err) {
    next(err);
  }
};


//更新文章
module.exports.updateArticles = async (req, res, next) => {
  try {
    //获取参数
    const { slug } = req.params
    //获取更新内容
    let data = req.body.article
    //获取更新文章
    let article = await Article.findByPk(slug, { include: Tag })
    //修改文章权限验证
    const loginUser = await User.findByPk(req.user.email)
    if (!loginUser) {
      throw new HttpException(401, '登录账号不存在！！！', "user not found!!!")
    }
    const authorEmail = article.userEmail
    if (loginUser.email !== authorEmail) {
      throw new HttpException(401, '没有修改权限（只有作者才能修改）！！！', " No permission to modify!!!")
    }
    //修改字段准备
    const title = data.title ? data.title : article.title
    const description = data.description ? data.description : article.description
    const body = data.body ? data.body : article.body
    // 更新数据
    const updateArticle = await article.update({ title, description, body })
    // 返回处理结果
    article = handleArticle(updateArticle, loginUser)
    // 响应数据
    res.status(200)
      .json({
        status: 1,
        message: '文章更新成功！！！',
        data: article
      })
  } catch (err) {
    next(err);
  }
};


//删除文章
module.exports.deleteArticles = async (req, res, next) => {
  try {
    //获取文章标识 slug
    const { slug } = req.params
    //获取文章
    let article = await Article.findByPk(slug, { include: Tag })
    if (!article) {
      throw new HttpException(401, '文章不存在！！！', 'The article does not exist!!!')
    }
    //获取当前用户信息
    const loginUser = await User.findByPk(req.user.email)
    if (!loginUser) {
      throw new HttpException(401, '登录账号不存在！！！', "user not found!!!")
    }
    const authorEmail = article.userEmail
    if (loginUser.email !== authorEmail) {
      throw new HttpException(401, '没有删除权限（只有作者才能删除）！！！', "Only authors can delete!!!")
    }
    //删除文章
    await Article.destroy({ where: { slug } })
    //响应数据
    res.status(200)
      .json({
        status: 1,
        message: '文章删除成功！！！'
      })
  } catch (err) {
    next(err);
  }
};


